package com;
/**
 * 多态：
 *      多态是面向对象三大特性之一
 *      什么是多态性？
 *      对象在运行过程中的多种形态。
 *      多态性我们大概可以分为两类：
 *      （1.）方法的重载与重写
 *      （2.）对象的多态性
 * 例如：用父类的引用指向子类对象（用大的类型去接收小的类型，向上转型，自动转换）
 * 结论：
 * 在编程时针对抽象类型的编写代码，称为面向抽象编程（或面向接口编程）
 * 父类通常都定义为抽象类，接口
 *
 *
 * 对象的多态性：对象多态性是从继承关系中的多个类中得来的
 * 小结：1.方法的重载与重写就是方法的多态性表现
 *      2.多个子类就是父类中的多种形态
 *      3.父类引用可以指向子类对象，自动转换
 *      4.子类对象指向父类引用需要强制转换（注意：类型不对会报异常）
 *      5.在实际开发中尽量使用父类引用（更利于扩展）
 * 父类的设计法则：
 *  通过instanceof关键字，我们可以很方便的检查对象的类型，但如果一个父类的子类过多，这样的判断还是很显的繁琐，那么如何设计一个父类呢？
 *  1.父类通常情况下都设计为抽象类或接口，其中优先考虑接口，如接口不能满足才考虑抽象类
 *  2.一个具体的类尽可能不去继承另一个具体的类，这样的好处是无需检查对象是否为父类的对象
 */
public class Polymorphism {
    public static void main(String[] args) {
        Chicken ye=new YeChicken("小野");
        Chicken jia=new JiaChicken("小家");
        eat(jia);
        eat(ye);
        Chicken jianjiao=new JIanjiaoChicken("尖叫鸡");
        eat(jianjiao);
    }
public static void eat(Chicken chicken){
/**
 * instanceof 是用于检查对象是否是指定的类型，通常在把父类引用强制转换为子类引用是要使用
 */
        if (chicken instanceof  JIanjiaoChicken){
            ((JIanjiaoChicken) chicken).sing();
        }else
            chicken.eat();


}
}

//Chicken鸡类

abstract class Chicken{
    private String name;
    public Chicken(String name){
        this.name=name;
    }
    public void setName(String name){
        this.name=name;
    }
    public String GetName(){
        return this.name;
    }
    public void eat(){
        System.out.println(this.GetName()+"喜欢吃吃吃");
    }
}

class YeChicken extends Chicken{

    public YeChicken(String name) {
        super(name);
    }

    public void eat(){
        System.out.println(this.GetName()+"喜欢吃虫子");
    }
}

class JiaChicken extends Chicken{
    public JiaChicken(String name){
        super(name);
    }
    public void eat(){
        System.out.println(this.GetName()+"喜欢吃大米");
    }
}

class JIanjiaoChicken extends Chicken{
     JIanjiaoChicken(String name){
        super(name);
    }
    public void sing(){
        System.out.println(this.GetName()+"会唱歌");
    }
}
